<?php

/**
 * RabbitCMS
 * 
 */
class News_Models_Article extends Rabbit_Db_Table_Abstract implements News_Models_Interfaces_Article {

    protected $_name = 'news_article';

    public function convert($entity) {
        return new News_Models_Entities_Article($entity);
    }

    public function getAll() {
        try {
            $db = $this->getAdapter();
            $select = $db->select()
                    ->from(array('a' => $this->_name), '*')
                    ->joinLeft(array('c' => $this->_prefix . 'category'), 'a.category_id = c.id', array('category_name' => 'c.name', 'category_slug' => 'c.slug'))
                    ->where('a.status <> ?', 'deleted')
                    ->order('a.created_date DESC');
            $rs = $db->query($select)->fetchAll();
            return ($rs == null) ? null : new Tomato_Model_RecordSet($rs, $this);
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return null;
        }
    }

    public function getById($id) {
        $row = $this->getAdapter()
                ->select()
                ->from(array('a' => $this->_prefix . 'news_article'))
                ->joinLeft(array('c' => $this->_prefix . 'category'), 'a.category_id = c.id', array('category_name' => 'c.name', 'category_slug' => 'c.slug'))
                ->where('a.id = ?', $id)
                ->limit(1)
                ->query()
                ->fetch();
        return (null == $row) ? null : new News_Models_Entities_Article($row);
    }

    public function add($article) {
        try {
            $article = $this->createRow($article->getProperties());
            if ($article->save()) {
                return $article->id;
            }
            return false;
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return false;
        }
    }

    public function edit($params) {
        try {

            return $this->update($params, array('id = ?' => $params['id']));
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return false;
        }
    }

    public function find($offset, $count, $exp = null, $order = 'id ASC') {
        $select = $this->getAdapter()
                ->select('*')
                ->from(array('a' => $this->_name))
                ->joinLeft(array('c' => $this->_prefix . 'category'), 'a.category_id = c.id', array('category_name' => 'c.name', 'category_slug' => 'c.slug'))
                /**
                 * @since 2.0.8
                 */
                ->where('a.language = ?', $this->_lang);

        if ($exp) {
            if (isset($exp['id'])) {
                $select->where('a.id = ?', $exp['id']);
            }
            if (isset($exp['category_id'])) {
                $select->where('a.category_id = ?', $exp['category_id']);
            }
            if (isset($exp['created_user_id'])) {
                $select->where('a.created_user_id = ?', $exp['created_user_id']);
            }
            if (isset($exp['status'])) {
                $select->where('a.status = ?', $exp['status']);
            }
            if (isset($exp['keyword'])) {
                $select->where("a.title LIKE '%" . addslashes($exp['keyword']) . "%'");
            }
        }
        $rs = $select->order('a.' . $order)
                ->limit($count, $offset)
                ->query()
                ->fetchAll();

        return new Tomato_Model_RecordSet($rs, $this);
    }

    public function count($exp = null) {
        $select = $this->getAdapter()
                ->select()
                ->from(array('a' => $this->_prefix . 'news_article'), array('num_articles' => 'COUNT(*)'))
                /**
                 * @since 2.0.8
                 */
                ->where('a.language = ?', $this->_lang);
        if ($exp) {
            if (isset($exp['id'])) {
                $select->where('a.id = ?', $exp['id']);
            }
            if (isset($exp['category_id'])) {
                $select->where('a.category_id = ?', $exp['category_id']);
            }
            if (isset($exp['created_user_id'])) {
                $select->where('a.created_user_id = ?', $exp['created_user_id']);
            }
            if (isset($exp['status'])) {
                $select->where('a.status = ?', $exp['status']);
            }
            if (isset($exp['keyword'])) {
                $select->where("a.title LIKE '%" . addslashes($exp['keyword']) . "%'");
            }
        }
        return $select->query()->fetch()->num_articles;
    }

    public function delete($id = null) {
        /**
         * Remove from collection of hot articles
         */
//        if ($id) {
//            $this->_conn->delete($this->_prefix . 'news_article_hot',
//                    array(
//                        'article_id = ?' => $id,
//            ));
//        }
        if ($id) {
            return parent::delete('id = ' . $id);
        } else {
            return $this->delete('status = ' . $this->getAdapter()->quote('deleted'));
        }

        return 0;
    }

    public function updateStatus($id, $status) {
        $user = Zend_Auth::getInstance()->getIdentity();
        $data = array('status' => $status);
        if ($status == 'actived') {
            $data['activate_user_id'] = $user->id;
            $data['activate_user_name'] = $user->username;
            $data['activate_date'] = date('Y-m-d H:i:s');
        }
        return $this->update($data, 'id = ' . $id);
    }

    public function getByTag($tagId, $offset, $count) {
        $rs = $this->_conn
                ->select()
                ->from(array('a' => $this->_prefix . 'news_article'))
                ->joinInner(array('ti' => $this->_prefix . 'tag_item_assoc'), 'a.article_id = ti.item_id', array())
                ->where('ti.tag_id = ?', $tagId)
                ->where('ti.item_name = ?', 'article_id')
                ->where('a.status = ?', 'active')
                /**
                 * @since 2.0.8
                 */
                ->where('a.language = ?', $this->_lang)
                ->group('a.article_id')
                ->order('a.article_id DESC')
                ->limit($count, $offset)
                ->query()
                ->fetchAll();
        return new rabbit_Model_RecordSet($rs, $this);
    }

    public function countByTag($tagId) {
        return $this->_conn
                        ->select()
                        ->from(array('a' => $this->_prefix . 'news_article'), array('num_articles' => 'COUNT(article_id)'))
                        ->joinInner(array('ti' => $this->_prefix . 'tag_item_assoc'), 'a.article_id = ti.item_id', array())
                        ->where('ti.tag_id = ?', $tagId)
                        ->where('ti.item_name = ?', 'article_id')
                        ->where('a.status = ?', 'active')
                        /**
                         * @since 2.0.8
                         */
                        ->where('a.language = ?', $this->_lang)
                        ->query()
                        ->fetch()
                ->num_articles;
    }

    public function increaseViews($articleId) {
        return $this->getAdapter()->update($this->_prefix . 'news_article', array(
                    'num_views' => new Zend_Db_Expr('num_views + 1'),
                        ), array(
                    'id = ?' => $articleId,
                ));
    }

    public function getByCategory($categoryId, $offset, $count) {
        $rs = $this->getAdapter()
                ->select()
                ->from(array('a' => $this->_prefix . 'news_article'), array('id', 'title', 'slug', 'content', 'summary', 'image_thumbnail', 'image_small', 'image_crop', 'image_large', 'image_original', 'activate_date', 'created_user_name', 'category_id', 'num_views'))
                //->joinInner(array('ac' => $this->_prefix . 'news_article_category_assoc'), 'a.article_id = ac.article_id', array('category_id'))
                ->joinInner(array('c' => $this->_prefix . 'category'), 'a.category_id = c.id', array('category_name' => 'name', 'category_slug' => 'slug'))
                ->where('a.category_id = ?', $categoryId)
                ->where('a.status = ?', 'actived')
                ->order('a.activate_date DESC')
                ->limit($count, $offset)
                ->query()
                ->fetchAll();
        return new Tomato_Model_RecordSet($rs, $this);
    }

    public function getCategoryIds($articleId) {
        $rs = $this->_conn
                ->select()
                ->from(array('a' => $this->_prefix . 'news_article_category_assoc'), array('category_id'))
                ->where('a.article_id = ?', $articleId)
                ->query()
                ->fetchAll();
        $categoryIds = array();
        if ($rs) {
            foreach ($rs as $row) {
                $categoryIds[] = $row->category_id;
            }
        }
        return $categoryIds;
    }

    public function addToCategory($articleId, $categoryId, $reset = false) {
        if ($reset) {
            $this->_conn->delete($this->_prefix . 'news_article_category_assoc', array(
                'article_id = ?' => $articleId,
            ));
        }
        $this->_conn->insert($this->_prefix . 'news_article_category_assoc', array(
            'category_id' => $categoryId,
            'article_id' => $articleId,
        ));
    }

    public function addHotArticle($articleId, $reset = false) {
        if ($reset) {
            $this->_conn->delete($this->_prefix . 'news_article_hot', array(
                'article_id = ?' => $articleId,
            ));
        }
        $this->_conn->insert($this->_prefix . 'news_article_hot', array(
            'article_id' => $articleId,
            'created_date' => date('Y-m-d H:i:s'),
            'ordering' => 1,
        ));
    }

    public function isHot($articleId) {
        $row = $this->_conn
                ->select()
                ->from(array('h' => $this->_prefix . 'news_article_hot'), array('num_articles' => 'COUNT(*)'))
                ->where('h.article_id = ?', $articleId)
                ->limit(1)
                ->query()
                ->fetch();
        return ($row->num_articles > 0);
    }

    public function getHotArticles($limit, $status = null) {
        $select = $this->getAdapter()
                ->select()
                ->from(array('a' => $this->_name))
                ->joinInner(array('h' => $this->_prefix . 'news_article_hot'), 'a.id = h.article_id', array('ordering'));
        /**
         * @since 2.0.8
         */
        //->where('a.language = ?', $this->_lang);
        if ($status) {
            $select->where('a.status = ?', $status);
        }
        $rs = $select->order('h.ordering')
                ->limit($limit)
                ->query()
                ->fetchAll();
        return $rs;
    }

    public function updateHotOrder($order, $articleId = null) {
        if (null == $articleId) {
            return $this->_conn->update($this->_prefix . 'news_article_hot', array(
                        'ordering' => $order,
                    ));
        } else {
            return $this->_conn->update($this->_prefix . 'news_article_hot', array(
                        'ordering' => $order,
                            ), array(
                        'article_id = ?' => $articleId,
                    ));
        }
    }

    /* ========== For translation =========================================== */

    public function getTranslations($item) {
        try {
            $rs = $this->getAdapter()
                    ->select()
                    ->from(array('a' => $this->_prefix . 'news_article'))
                    ->joinInner(array('tr' => $this->_prefix . 'core_translation'), 'tr.item_class = ?
						AND (tr.item_id = ? OR tr.source_item_id = ?)
						AND (tr.item_id = a.id OR tr.source_item_id = a.id)', array('tr.source_item_id'))
                    ->group('a.id')
                    ->bind(array(
                        'News_Models_Entities_Article', //Changed by Tronghm
                        $item->id,
                        $item->id,
                    ))
                    ->query()
                    ->fetchAll();
            return (null == $rs) ? null : new Tomato_Model_RecordSet($rs, $this);
        } catch (Exception $ex) {
            return null;
            echo $ex->getMessage();
        }
    }

    public function getTranslatable($lang, $count) {
        $rs = $this->getAdapter()
                ->select()
                ->from(array('a' => $this->_prefix . 'news_article'))
                ->joinLeft(array('tr' => $this->_prefix . 'core_translation'), 'tr.source_item_id = a.id
							AND tr.item_class = ? 
							AND tr.language = ?', array('translatable' => '(tr.item_id IS NULL)'))
                ->where('a.language <> ?')
                ->order('a.id DESC')
                ->limit($count)
                ->bind(array(
                    $this->_lang,
                    'News_Models_Entities_Article',
                    $lang
                ))
                ->query()
                ->fetchAll();
        return new Tomato_Model_RecordSet($rs, $this);
    }

    public function getSource($article) {
        $row = $this->getAdapter()
                ->select()
                ->from(array('a' => $this->_prefix . 'news_article'))
                ->joinInner(array('tr' => $this->_prefix . 'core_translation'), 'a.id = tr.source_item_id', array())
                ->where('tr.item_class = ?', 'News_Models_Entities_Article')
                ->where('tr.item_id = ?', $article->id)
                ->limit(1)
                ->query()
                ->fetch();
        return (null == $row) ? null : new News_Models_Entities_Article($row);
    }

    /**
     * Get featured articles with limit in categoryId and not it $excludeCategoryId
     * @param int $limit
     * @param int $categoryId
     * @param string $excludeCategoryId
     * @author TrongHM
     */
    public function getFeatured($limit, $categoryId, $excludeCategoryId) {

        $select = $this->getAdapter()->select()
                ->from(array('a' => $this->_name))
                ->joinLeft(array('c' => $this->_prefix . 'category'), 'a.category_id = c.id', array('category_name' => 'c.name', 'category_slug' => 'c.slug'))
                ->where('a.featured = 1')
                ->where('a.status = ?', 'actived')
                ->where('a.language = ?', $this->_lang)
                ->limit($limit);
        if ($categoryId && is_numeric($categoryId)) {
            $select->where('a.category_id =?', $categoryId);
        } else {
            $pattern = '/[\d,]+/';
            if ($excludeCategoryId && preg_match($pattern, $excludeCategoryId)) {
                $select->where('a.category_id NOT IN ?', $excludeCategoryId);
            }
        }
        $rs = $select->query()->fetchAll();

        return new Tomato_Model_RecordSet($rs, $this);
    }

    /**
     * Update rating of article
     * @param int $id
     * @param float $rate
     */
    public function rate($id, $rate) {
        $rating = $this->getAdapter()
                        ->select()
                        ->from(array('a' => $this->_name), array('rating' => 'a.rating'))
                        ->where('id = ?', $id)
                        ->limit(1)
                        ->query()
                        ->fetch()->rating;
        if ($rating && $rating != '') {
            $rating = Zend_Json::decode($rating);
            $newRate = ($rating['avg'] * $rating['num'] + $rate) / ($rating['num'] + 1);
            $newRate = array('avg' => $newRate, 'num' => $rating['num'] + 1);
            $newRate = Zend_Json::encode($newRate);
        } else {
            $newRate = array('avg' => $rate, 'num' => 1);
            $newRate = Zend_Json::encode($newRate);
        }
        return parent::update(array('rating' => $newRate), array('id = ?' => $id));
    }

    public function getLimit($limit = 20) {
        try {
            $db = $this->getAdapter();
            $select = $db->select()
                    ->from(array('a' => $this->_name), '*')
                    ->joinLeft(array('c' => $this->_prefix . 'category'), 'a.category_id = c.id', array('category_name' => 'c.name', 'category_slug' => 'c.slug'))
                    ->where('a.status <> ?', 'deleted')
                    ->where('a.language = ?', $this->_lang)
                    ->order('a.created_date DESC')
                    ->limit($limit);
            $rs = $db->query($select)->fetchAll();
            return ($rs == null) ? null : new Tomato_Model_RecordSet($rs, $this);
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return null;
        }
    }

    public function getRelate($article_id, $limit = 10) {
        try {
            if ($article_id) {
                $rs = $this->getAdapter()
                                ->select()
                                ->from(array('a' => $this->_name), '*')
                                ->joinLeft(array('c' => $this->_prefix . 'category'), 'a.category_id = c.id', array('category_name' => 'c.name', 'category_slug' => 'c.slug'))
                                ->where('a.id <> ?', $article_id)
                                ->order('a.created_date DESC')
                                ->limit($limit)
                                ->query()->fetchAll();
                return ($rs == null) ? null : new Tomato_Model_RecordSet($rs, $this);
            }
            return null;
        } catch (Exception $ex) {
            echo $ex->getMessage();
            return null;
        }
    }

}
